local S = minetest.get_translator("advtrains_doc_integration")
local fsescape = minetest.formspec_escape

local function map(tbl, func)
	local t = {}
	for k, v in pairs(tbl or {}) do
		t[k] = func(v)
	end
	return t
end

if doc.sub.items then
	local register_factoid = doc.sub.items.register_factoid
	local function group_factoid(cat, gr, f)
		register_factoid(cat, "groups", function(_, def)
			return f(def.groups[gr] or 0) or ""
		end)
	end
	for cat, cinfo in pairs{
		nodes = {
			not_blocking_trains = "This block does not block trains.",
			save_in_at_nodedb = "This block is saved in the Advtrains node database.",
		},
	} do
		for group, ginfo in pairs(cinfo) do
			local tp = type(ginfo)
			if tp == "string" then
				group_factoid(cat, group, function(x)
					if x > 0 then
						return ginfo
					end
				end)
			elseif tp == "function" then
				group_factoid(cat, group, ginfo)
			end
		end
	end
	register_factoid("nodes", "groups", function(_, ndef)
		if ndef.advtrains then
			if ndef.advtrains.set_aspect then
				return "This is a signal with a variable aspect."
			elseif ndef.advtrains.get_aspect then
				return "This is a signal with a static aspect."
			end
		end
		return ""
	end)
end

doc.add_category("advtrains_wagons", {
	name = S("Wagons"),
	build_formspec = doc.entry_builders.formspec,
})

local function addlist(lst, tbl, title, fallback1, fallback2, mapf)
	if not tbl then
		if fallback2 then
			table.insert(lst, fallback2)
		elseif fallback2 == false and fallback1 then
			table.insert(lst, fallback1)
		end
	elseif next(tbl) ~= nil then
		table.insert(lst, title)
		for k, v in pairs(tbl) do
			if mapf then
				k = mapf(k, v)
			end
			table.insert(lst, "* " .. k)
		end
	elseif fallback1 then
		table.insert(lst, fallback1)
	end
end

local function get_coupler_name(n)
	return advtrains.coupler_types[n] or n
end

local function doc_register_wagon(itemname)
	local prototype = advtrains.wagon_prototypes[itemname]
	local itemdef = minetest.registered_items[itemname]
	local desctext = {}
	addlist(desctext, prototype.drives_on, S("Drives on:"))
	addlist(desctext, prototype.coupler_types_front, S("Compatible couplers (front):"), S("No front couplers"), S("Universal front coupler"), get_coupler_name)
	addlist(desctext, prototype.coupler_types_back, S("Compatible couplers (back):"), S("No back couplers"), S("Universal back coupler"), get_coupler_name)
	if prototype.wagon_span then
		table.insert(desctext, S("Wagon span: @1", 2*prototype.wagon_span))
	end
	table.insert(desctext, S("Max speed: @1 m/s", prototype.max_speed or "not defined"))
	table.insert(desctext, S("Motive power: " .. (prototype.is_locomotive and "yes" or "no")))
	if prototype.has_inventory then
		addlist(desctext, prototype.inventory_list_sizes, S("Cargo inventory size:"), S("Cargo inventory: yes"), false, function(k, v)
			return string.format("%s: %s", k, v)
		end)
	else
		table.insert(desctext, S("Cargo inventory: no"))
	end
	local pax, driver = 0, 0
	if prototype.seats and prototype.seat_groups then
		for _, v in pairs(prototype.seats) do
			if prototype.seat_groups[v.group].driving_ctrl_access then
				driver = driver + 1
			else
				pax = pax + 1
			end
		end
	end
	table.insert(desctext, S("Passenger seats: @1", pax))
	table.insert(desctext, S("Driver seats: @1", driver))
	addlist(desctext, prototype.drops, S("Drops:"), S("Drops nothing"), false, function(_, v) return v end)


	local x0, y0 = doc.FORMSPEC.ENTRY_START_X, doc.FORMSPEC.ENTRY_START_Y
	local x1, y1 = doc.FORMSPEC.ENTRY_END_X+0.75, doc.FORMSPEC.ENTRY_END_Y
	local width, height = x1-x0, y1-y0
	local mside = height/2

	local mesh = fsescape(prototype.mesh or "")
	local textures = table.concat(map(prototype.textures, fsescape), ",")
	local fstext = {
		doc.widgets.text(table.concat(desctext, "\n"), x0, y0, width-mside, height),
		string.format("item_image[%f,%f;%f,%f;%s]", x1-mside, y0, mside, mside, fsescape(itemname)),
		"style[wagon_model;bgcolor=#000]",
		string.format("model[%f,%f;%f,%f;%s;%s;%s]", x1-mside, y1-mside+0.625, mside, mside, "wagon_model", mesh, textures),
	}
	minetest.override_item(itemname, {_doc_items_create_entry = false})
	doc.add_entry("advtrains_wagons", itemname, {
		name = string.split(itemdef.description, "\n", true)[1],
		data = table.concat(fstext),
	})
end

for k in pairs(advtrains.wagon_prototypes) do
	doc_register_wagon(k)
end
